package dbx

import (
	"gitee.com/zhongguo168a/gocodes/myx/errorx"
	"gitee.com/zhongguo168a/gocodes/myx/identx"
)

func NewDelay() (obj *DelayQueue) {
	obj = &DelayQueue{}
	obj.saveKey = identx.GenOne()
	obj.items = map[string]*DelayItem{}
	obj.origins = map[string]*OriginItem{}
	return
}

// NewDelayByKey 一个键值可以用于标识一个玩家，一个工会，一个游戏进程等一定时间内产生的数据变化
func NewDelayByKey(key string) (obj *DelayQueue) {
	obj = &DelayQueue{}
	obj.saveKey = key
	obj.items = map[string]*DelayItem{}
	obj.origins = map[string]*OriginItem{}
	return
}

// DelayQueue 延时更新队列
// 只能用于具有[_id]字段的对象的更新
// 记录下对象的变化字段，通过执行Save方法一次更新到数据库中
type DelayQueue struct {
	saveKey string

	// table+"/" + ident
	items map[string]*DelayItem
	// 更新时记录下原始的数据，回滚时使用
	origins        map[string]*OriginItem
	commitAfters   []*AfterHandler
	rollbackAfters []*AfterHandler
	// 是否已经过期
	isExpired bool
}

func (delayQueue *DelayQueue) GetSaveKey() string {
	return delayQueue.saveKey
}

func (delayQueue *DelayQueue) Save() (err error) {
	err = saveRoot.SaveByGroup(delayQueue.saveKey)
	return
}

func (delayQueue *DelayQueue) getOrNewItem(model IDBModel) *DelayItem {
	table, has := GetTable(model.DBTable())
	if !has {
		panic(errorx.New("table not found: " + model.DBTable()))
	}
	docIdent := GetDocumentIdent(model.DBTable(), model.DBIdent())
	delayItem := delayQueue.items[docIdent]
	if delayItem == nil {
		delayItem = NewDelayItem(model.DBTable(), model.DBIdent())
		delayItem.Database = table.GetDatabase()
		delayItem.Query = model.DBQuery()
		delayQueue.items[docIdent] = delayItem
	}
	return delayItem
}
